// Copyright 2013-2018 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace Serilog.Settings.KeyValuePairs;

/// <summary>
/// Contains "fake extension" methods for the Serilog configuration API.
/// By default the settings knows how to find extension methods, but some configuration
/// are actually "regular" method calls and would not be found otherwise.
///
/// This static class contains internal methods that can be used instead.
///
/// See also <seealso cref="CallableConfigurationMethodFinder"/>
/// </summary>
static class SurrogateConfigurationMethods
{
    static readonly Dictionary<Type, MethodInfo[]> SurrogateMethodCandidates = typeof(SurrogateConfigurationMethods)
        .GetTypeInfo().DeclaredMethods
        .GroupBy(m => m.GetParameters().First().ParameterType)
        .ToDictionary(g => g.Key, g => g.ToArray());

    internal static readonly MethodInfo[] WriteTo = SurrogateMethodCandidates[typeof(LoggerSinkConfiguration)];
    internal static readonly MethodInfo[] AuditTo = SurrogateMethodCandidates[typeof(LoggerAuditSinkConfiguration)];
    internal static readonly MethodInfo[] Enrich = SurrogateMethodCandidates[typeof(LoggerEnrichmentConfiguration)];
    internal static readonly MethodInfo[] Destructure = SurrogateMethodCandidates[typeof(LoggerDestructuringConfiguration)];
    internal static readonly MethodInfo[] Filter = SurrogateMethodCandidates[typeof(LoggerFilterConfiguration)];

    internal static LoggerConfiguration Sink(
        LoggerSinkConfiguration loggerSinkConfiguration,
        ILogEventSink sink,
        LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
        LoggingLevelSwitch? levelSwitch = null)
    {
        return loggerSinkConfiguration.Sink(sink, restrictedToMinimumLevel, levelSwitch);
    }

    internal static LoggerConfiguration Sink(
        LoggerAuditSinkConfiguration auditSinkConfiguration,
        ILogEventSink sink,
        LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
        LoggingLevelSwitch? levelSwitch = null)
    {
        return auditSinkConfiguration.Sink(sink, restrictedToMinimumLevel, levelSwitch);
    }

    internal static LoggerConfiguration With(LoggerEnrichmentConfiguration loggerEnrichmentConfiguration, ILogEventEnricher enricher)
    {
        return loggerEnrichmentConfiguration.With(enricher);
    }

    internal static LoggerConfiguration FromLogContext(LoggerEnrichmentConfiguration loggerEnrichmentConfiguration)
    {
        return loggerEnrichmentConfiguration.FromLogContext();
    }

    internal static LoggerConfiguration With(LoggerDestructuringConfiguration loggerDestructuringConfiguration,
        IDestructuringPolicy policy)
    {
        return loggerDestructuringConfiguration.With(policy);
    }

    internal static LoggerConfiguration AsScalar(LoggerDestructuringConfiguration loggerDestructuringConfiguration,
        Type scalarType)
    {
        return loggerDestructuringConfiguration.AsScalar(scalarType);
    }

    internal static LoggerConfiguration ToMaximumCollectionCount(LoggerDestructuringConfiguration loggerDestructuringConfiguration,
        int maximumCollectionCount)
    {
        return loggerDestructuringConfiguration.ToMaximumCollectionCount(maximumCollectionCount);
    }

    internal static LoggerConfiguration ToMaximumDepth(LoggerDestructuringConfiguration loggerDestructuringConfiguration,
        int maximumDestructuringDepth)
    {
        return loggerDestructuringConfiguration.ToMaximumDepth(maximumDestructuringDepth);
    }

    internal static LoggerConfiguration ToMaximumStringLength(LoggerDestructuringConfiguration loggerDestructuringConfiguration,
        int maximumStringLength)
    {
        return loggerDestructuringConfiguration.ToMaximumStringLength(maximumStringLength);
    }

    internal static LoggerConfiguration With(LoggerFilterConfiguration loggerFilterConfiguration,
        ILogEventFilter filter)
    {
        return loggerFilterConfiguration.With(filter);
    }
}
